package com.youlu.campus.service.visitor;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.google.common.collect.Lists;
import com.youlu.campus.common.utils.DateTimeUtils;
import com.youlu.campus.entity.*;
import com.youlu.campus.entity.VO.req.WechatMiniUserQueryReq;
import com.youlu.campus.entity.VO.res.ExportMiniUserRes;
import com.youlu.campus.service.university.UniversityService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.repository.support.PageableExecutionUtils;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Slf4j
@Service
public class WechatMiniUserService {


    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private UserInfoExtendService userInfoExtendService;

    @Autowired
    private UniversityService universityService;

    private final Integer MAX_COUNT = 300000;


    public void export(WechatMiniUserQueryReq req) {
        Integer currentPageNo = 1;
        Integer pageSize = 10000;
        log.info("【导出小程序基本用户】start");
        List<ExportMiniUserRes> exportResult = Lists.newLinkedList();
        while (true) {
            log.info("【导出小程序基本用户】正在导出 ..... 第" + currentPageNo + "页  start");
            req.setPageNo(currentPageNo);
            req.setPageSize(pageSize);
            Page<WechatMiniUserPO> pageList = this.list(req);
            List<WechatMiniUserPO> list = pageList.getContent();
            if (CollectionUtils.isEmpty(list)) {
                log.info("【导出小程序基本用户】分页获取数据库 end ");
                break;
            }
            List<ExportMiniUserRes> result = list.stream().map(user -> {
                ExportMiniUserRes exportUser = new ExportMiniUserRes();
                exportUser.setName(user.getName());
                exportUser.setOpenId(user.getOpenId());
                exportUser.setUniversityName(user.getUniversityName());
                exportUser.setCreateTime(DateTimeUtils.formatDateTime(user.getCreatedTime()));
                exportUser.setMobile(user.getMobile());
                exportUser.setUniversityType(user.getUniversityType());
                return exportUser;
            }).collect(Collectors.toList());
            exportResult.addAll(result);
            currentPageNo++;
        }
        List<ExportMiniUserRes> exportResult2 = null;
        try {
            Integer skip = 0;
            do {
                String fileName =
                        "小程序用户信息" + "-" + System.currentTimeMillis() + ExcelTypeEnum.XLSX.getValue();
                String file = "/data/app/file/" + fileName;
                ExcelWriter excelWriter = EasyExcel.write(file, ExportMiniUserRes.class).build();
                exportResult2 =
                        exportResult.stream().skip(skip * MAX_COUNT).limit(MAX_COUNT).collect(Collectors.toList());
                WriteSheet writeSheet = EasyExcel.writerSheet(1, "小程序用户信息").build();
                if (CollectionUtils.isNotEmpty(exportResult2)) {
                    excelWriter.write(exportResult2, writeSheet);
                }
                if (Objects.nonNull(excelWriter)) {
                    excelWriter.finish();
                }
                skip++;
            } while (Objects.nonNull(exportResult2) && !exportResult2.isEmpty());

        } catch (Exception e) {
            log.info("【导出小程序基本用户】error ", e);
            return;
        } finally {
            exportResult.clear();
            if (CollectionUtils.isNotEmpty(exportResult2)) {
                exportResult2.clear();
            }
        }
        log.info("【导出小程序基本用户】end");
    }


    public Page<WechatMiniUserPO> list(WechatMiniUserQueryReq req) {
        String mobile = req.getMobile();
        String openId = req.getOpenId();
        Integer pageNo = req.getPageNo();
        Integer pageSize = req.getPageSize();
        boolean choiced = false;
        Query query = new Query();
        if (StringUtils.isNotBlank(mobile)) {
            query.addCriteria(Criteria.where("mobile").is(req.getMobile()));
            choiced = true;
        }
        if (StringUtils.isNotBlank(openId)) {
            query.addCriteria(Criteria.where("openId").is(openId));
            choiced = true;
        }
        Long count;
        if(choiced){
            count = mongoTemplate.count(query, WechatMiniUserPO.class);
        }else {
            count = 1000L;
        }
        PageRequest pageRequest = PageRequest.of(pageNo - 1, pageSize);
//        query.with(new Sort(Sort.Direction.DESC, "createdTime"));
        Sort sort = Sort.by(Sort.Direction.DESC, "createdTime");
        query.with(sort);
        List<WechatMiniUserPO> userList = mongoTemplate.find(query.with(pageRequest), WechatMiniUserPO.class);
        if (CollectionUtils.isNotEmpty(userList)) {
            userList.stream().forEach(user -> {
                UserInfoExtend userExt = userInfoExtendService.findByUserId(user.getAccountInfoId());
                if (StringUtils.isBlank(user.getName())) {
                    if (Objects.nonNull(userExt)) {
                        user.setName(userExt.getName());
                    }
                }
                if (StringUtils.isBlank(user.getMobile())) {
                    if (Objects.nonNull(userExt)) {
                        user.setMobile(userExt.getMobile());
                    }
                }
                if (StringUtils.isBlank(user.getUniversityId())) {
                    if (Objects.nonNull(userExt)) {
                        user.setUniversityId(userExt.getUniversityId());
                    }
                }
                if (StringUtils.isNotBlank(user.getUniversityId())) {
                    UniversityInfo universityInfo = universityService.get(user.getUniversityId());
                    if (Objects.nonNull(universityInfo)) {
                        user.setUniversityType(universityInfo.getType());
                    }
                }
                if (StringUtils.isBlank(user.getUniversityName())) {
                    if (Objects.nonNull(userExt)) {
                        user.setUniversityName(userExt.getUniversityName());
                    }
                }
            });
        }

        return PageableExecutionUtils.getPage(userList, pageRequest, () -> count);
    }

    public void updateUserInfo(WechatMiniUserPO updateUser) {
        if (Objects.isNull(updateUser)) {
            return;
        }
        if (StringUtils.isBlank(updateUser.getAccountInfoId())) {
            return;
        }
        if (StringUtils.isAllBlank(updateUser.getName(), updateUser.getUniversityId(),
                updateUser.getUniversityName())) {
            log.info("【修改小程序用户信息】姓名:{}或学校ID:{} 或学校:{}不能未空", updateUser.getName(), updateUser.getUniversityId(),
                    updateUser.getUniversityName());
            return;
        }
        Query query = new Query();
        query.addCriteria(Criteria.where("accountInfoId").is(updateUser.getAccountInfoId()));
        Update update = new Update();
        if (StringUtils.isNotBlank(updateUser.getName())) {
            update.set("name", updateUser.getName());
        }
        if (StringUtils.isNotBlank(updateUser.getUniversityId())) {
            update.set("universityId", updateUser.getUniversityId());
        }
        if (StringUtils.isNotBlank(updateUser.getUniversityName())) {
            update.set("universityName", updateUser.getUniversityName());
        }
        this.mongoTemplate.updateMulti(query, update, WechatMiniUserPO.class);
        query = new Query();
        query.addCriteria(Criteria.where("userId").is(updateUser.getAccountInfoId()));
        this.mongoTemplate.updateFirst(query, update, UserInfoExtend.class);
        query.addCriteria(Criteria.where("platform").is("wechat-mini"));
        this.mongoTemplate.updateMulti(query, update, UserParticipateActivityInfo.class);
        this.mongoTemplate.updateFirst(new Query().addCriteria(Criteria.where("id").is(updateUser.getAccountInfoId())),
                update, UserPO.class);
    }
}
